package com.derbysoft.defender.mp.api.requester;

import com.derbysoft.defender.mp.api.request.UserParameter;
import com.derbysoft.defender.mp.api.response.UserDetail;
import com.derbysoft.defender.mp.api.response.UserDetails;
import com.derbysoft.defender.mp.api.response.UserSummary;

/**
 * <p>some description here.</p>
 * Created by Afee Lee on 2017-03-22 08:36
 *
 * @author Afee Lee
 * @version 1.0
 * @see Object
 * @since 1.8
 */
public class UserRequester extends AbstractRequester {
    private static final String URL_LIST_USER = "https://api.weixin.qq.com/cgi-bin/user/get?access_token={access_token}";
    private static final String URL_GET_USER = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={access_token}&openid={openid}&lang={lang}";
    private static final String URL_BATCH_GET_USER = "https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token={access_token}";

    private static final String FRAGMENT_NEXT_OPENID = "&next_openid=";
    public static final String LANG_DEFAULT = "zh_CN"; //简体
    public static final String LANG_TW = "zh_TW"; //繁体
    public static final String LANG_EN = "en";    //英语

    private String accessToken;

    public UserRequester(String accessToken) {
        this.accessToken = accessToken;
    }

    public String getAccessToken() {
        return accessToken;
    }

    public UserSummary listUsers() {
        return listUsers(null);
    }

    /**
     * 公众号可通过本接口来获取帐号的关注者列表，关注者列表由一串OpenID（加密后的微信号，每个用户对每个公众号的OpenID是唯一的）组成。
     * 一次拉取调用最多拉取10000个关注者的OpenID，可以通过多次拉取的方式来满足需求。<br/>
     * 接口调用请求说明<br/>
     * http请求方式: GET（请使用https协议）<br/>
     * https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID
     * <pre>
     * 参数	是否必须	说明
     * access_token	是	调用接口凭证
     * next_openid	是	第一个拉取的OPENID，不填默认从头开始拉取
     * </pre>
     * 返回说明<br/>
     * 正确时返回JSON数据包：<br/>
     * {"total":2,"count":2,"data":{"openid":["","OPENID1","OPENID2"]},"next_openid":"NEXT_OPENID"}
     * <pre>
     * 参数	说明
     * total	关注该公众账号的总用户数
     * count	拉取的OPENID个数，最大值为10000
     * data	列表数据，OPENID的列表
     * next_openid	拉取列表的最后一个用户的OPENID
     * </pre>
     * <p/>
     * 错误时返回JSON数据包（示例为无效AppID错误）：
     * <pre>{"errcode":40013,"errmsg":"invalid appid"}</pre>
     * <p/>
     * <strong>附：关注者数量超过10000时</strong><br/>
     * 当公众号关注者数量超过10000时，可通过填写next_openid的值，从而多次拉取列表的方式来满足需求。
     * 具体而言，就是在调用接口时，将上一次调用得到的返回中的next_openid值，作为下一次调用中的next_openid值。<br/>
     *
     * @return users
     */
    public UserSummary listUsers(String nextOpenid) {
        String url = URL_LIST_USER;

        if (nextOpenid != null && !nextOpenid.isEmpty()) {
            url += FRAGMENT_NEXT_OPENID + nextOpenid;
        }

        return getForEntity(url, UserSummary.class, accessToken);
    }

    /**
     * 获取用户基本信息(UnionID机制)
     * <p/>
     * 在关注者与公众号产生消息交互后，公众号可获得关注者的OpenID（加密后的微信号，每个用户对每个公众号的OpenID是唯一的。对于不同公众号，同一用户的openid不同）。
     * 公众号可通过本接口来根据OpenID获取用户基本信息，包括昵称、头像、性别、所在城市、语言和关注时间。
     * <p/>
     * 请注意，如果开发者有在多个公众号，或在公众号、移动应用之间统一用户帐号的需求，需要前往微信开放平台（open.weixin.qq.com）绑定公众号后，才可利用UnionID机制来满足上述需求。
     * <p/>
     * UnionID机制说明：
     * 开发者可通过OpenID来获取用户基本信息。特别需要注意的是，如果开发者拥有多个移动应用、网站应用和公众帐号，可通过获取用户基本信息中的unionid来区分用户的唯一性，
     * 因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号，用户的unionid是唯一的。换句话说，同一用户，对同一个微信开放平台下的不同应用，unionid是相同的。
     * <p/>
     * 获取用户基本信息（包括UnionID机制）<br/>
     * 开发者可通过OpenID来获取用户基本信息。请使用https协议。<br/>
     * 接口调用请求说明<br/>
     * http请求方式: GET <br/>
     * https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
     * <p/>
     * <pre>
     * 参数说明
     * 参数	是否必须	说明
     * access_token	是	调用接口凭证
     * openid	是	普通用户的标识，对当前公众号唯一
     * lang	否	返回国家地区语言版本，zh_CN 简体，zh_TW 繁体，en 英语
     * </pre>
     *
     * @param openid   openid of user
     * @param language language to show
     * @return user detail info
     */
    public UserDetail getUser(String openid, String language) {
        if (language == null || language.isEmpty()) {
            language = LANG_DEFAULT;
        }

        return getForEntity(URL_GET_USER, UserDetail.class, accessToken, openid, language);
    }

    public UserDetail getUser(String openid) {
        return getUser(openid, null);
    }

    /**
     * 开发者可通过该接口来批量获取用户基本信息。最多支持一次拉取100条。<br/>
     * 接口调用请求说明<br/>
     * http请求方式: POST<br/>
     * https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=ACCESS_TOKEN<br/>
     * <p/>
     * POST数据示例
     * <pre>
     * {
     * "user_list": [
     * {
     * "openid": "otvxTs4dckWG7imySrJd6jSi0CWE",
     * "lang": "zh-CN"
     * },
     * {
     * "openid": "otvxTs_JZ6SEiP0imdhpi50fuSZg",
     * "lang": "zh-CN"
     * }
     * ]
     * }
     * </pre>
     * <p/>
     * 参数说明
     * <pre>
     * 参数	是否必须	说明
     * openid	是	用户的标识，对当前公众号唯一
     * lang	否	国家地区语言版本，zh_CN 简体，zh_TW 繁体，en 英语，默认为zh-CN
     * </pre>
     */
    public UserDetails batchGetUsers(UserParameter parameter) {
        return postForEntity(URL_BATCH_GET_USER, parameter, UserDetails.class, accessToken);
    }
}
